package Day_0216.JVM.GarbageCollection;

/**
 * @author zxc
 * @date 2023/02/16 18:05
 **/
public class Memory_Allocation_Policy {
    public static void main(String[] args) {
        /**
         * Java的内存分配策略
         * ===》
         * 1.对象的内存分配，通常是在 Java 堆上分配;
         * （随着虚拟机优化技术的诞生，某些场景下也会在栈上分配，后面会详细介绍），
         * （1）对象主要分配在新生代的 Eden 区，如果启动了本地线程缓冲，将按照线程优先在TLAB（Thread Local Allcation Buffer）上分配。
         * （2）少数情况下也会直接在老年代上分配。
         * ===》
         * 总的来说分配规则不是百分百固定的，其细节取决于哪一种垃圾收集器组合以及虚拟机相关参数有关，
         * 但是虚拟机对于内存的分配还是会遵循以下几种「普世」规则：
         *
         * 2.对象优先在 Eden 区分配
         * （1）多数情况，对象都在新生代 Eden 区分配。
         * （2）当 Eden 区分配没有足够的空间进行分配时，虚拟机将会发起一次 Minor GC。
         * （3）如果本次 GC 后还是没有足够的空间，则将启用分配担保机制在老年代中分配内存。
         * ===》
         * Minor GC && Full/Major GC的概念 ：
         * 1）这里我们提到 Minor GC，如果你仔细观察过 GC 日常，通常我们还能从日志中发现 Major GC/FullGC。
         * 2）Minor GC 是指发生在新生代的 GC，因为 Java 对象大多都是朝生夕死，所有 Minor GC 非常频繁，一般回收速度也非常快；
         * 3）Major GC/Full GC 是指发生在老年代的 GC，出现了 Major GC 通常会伴随至少一次 Minor GC。
         * 4）Major GC 的速度通常会比 Minor GC 慢 10 倍以上。
         *
         * 3.大对象直接进入老年代
         * （1）所谓大对象，是指需要大量连续内存空间的对象，
         *  频繁出现大对象是致命的，会导致在内存还有不少空间的情况下，提前触发 GC ，以获取足够的连续空间来安置新对象。
         * （2）前面介绍过新生代使用的是，复制算法来处理垃圾回收的，
         *  如果大对象直接在新生代分配就会导致 Eden 区和两个 Survivor 区之间发生大量的内存复制。
         *  因此对于大对象都会直接在老年代进行分配。长期存活对象将进入老年代
         *
         * 4.虚拟机采用分代收集的思想，来管理内存，
         * （1）内存回收时，就必须判断哪些对象应该放在新生代，哪些对象应该放在老年代。
         * （2）因此，虚拟机给每个对象定义了一个对象年龄的计数器，
         *  如果对象在 Eden 区出生，并且能够被 Survivor 容纳，将被移动到 Survivor 空间中，这时设置对象年龄为 1。
         *  对象在 Survivor 区中每「熬过」一次 Minor GC 年龄就加 1，当年龄达到一定程度（默认 15） 就会被晋升到老年代。
         *
         * 5.对象分配规则
         * （1）对象优先分配在Eden区，如果Eden区没有足够的空间时，虚拟机执行一次Minor GC。
         * （2）大对象直接进入老年代（大对象是指需要大量连续内存空间的对象）。
         *  这样做的目的是避免在Eden区和两个Survivor区之间发生大量的内存拷贝（新生代采用复制算法收集内存）。
         * （3）长期存活的对象进入老年代。
         *  虚拟机为每个对象定义了一个年龄计数器，如果对象经过了1次Minor GC那么对象会进入Survivor区，
         *  之后每经过一次Minor GC那么对象的年龄加1，知道达到阀值对象进入老年区。
         * （4）动态判断对象的年龄。
         *  如果Survivor区中，相同年龄的所有对象大小总和 大于 Survivor空间的一半，年龄大于或等于该年龄的对象可以直接进入老年代。
         *
         * 6.空间分配担保机制 ：即，每次Minor GC之前，都会去计算 之前每次从年轻代移动到老年代的对象平均大小 是否大于 老年区剩余内存大小;
         * （1）每次进行Minor GC时，JVM会计算 之前每次从Survivor区移至老年区的对象的平均大小;
         * （2）如果这个值大于老年区的剩余值大小，则进行一次Full GC;
         * （3）如果小于的话，则检查HandlePromotionFailure设置，如果true，则只进行Minor GC,如果false，则进行Full GC
         *
         */
    }
}
